<template>
  <Split v-model="split" class="apidoc">
    <template #left>
      <div class="content" ref="content">
        <div class="content-left">
          <div class="header">
            <img class="avatat" :src="params.logo" alt="" />
            <div class="title">{{ params.name }}</div>
          </div>
          <docMenu ref="treeRef" :projectId="params.id" @node-click="handleTreeNodeClick" />
        </div>
        <div class="content-mid" v-loading="loading">
          <documentView :tabData="tabData" @to-debug="toDebug" @to-copy="toCopy" @to-export="toExport" />
        </div>
      </div>
    </template>
    <template #right>
      <div class="debug" v-loading="debugloading">
        <div class="debug-header">
          <Close class="close" @click="closeDebug" />
          <span>在线运行</span>
          <div class="environment-select">
            <el-select style="width: 150px" v-model="environment" placeholder="请选择环境配置" @change="changeEnv">
              <el-option v-for="item in environments" :key="item.id" :label="item.name" :value="item.id" />
              <template #footer>
                <el-button type="primary" plain @click="openDialog()">管理环境</el-button>
              </template>
            </el-select>
          </div>
        </div>
        <operation :tabData="tabData" @debug="handleDebug" @query-com-value="handleQueryValue" />
      </div>
    </template>
  </Split>
  <!-- 环境弹窗 -->
  <environmentDialog :tabData="tabData" ref="environmentRef" @success="getEnvironments" />
</template>

<script setup lang="ts">
import { Close } from '@element-plus/icons-vue'
import * as DebugApi from '@/api/debug'
import * as apihubApi from '@/api/apihub'
import * as environmentApi from '@/api/environment'
import docMenu from './components/docMenu.vue'
import documentView from './components/documentView.vue'
import operation from './components/operation.vue'
import environmentDialog from './components/environmentDialog.vue'
import { isValidDateTime } from '@/utils/dateUtil'
import { useDebugStore } from '@/store/modules/debug'
import { ElMessageBox, ElNotification, ElButton } from 'element-plus'
import { useAppStore } from '@/store/modules/app'
import download from '@/utils/download'
const appStore = useAppStore()
const message = useMessage() // 消息弹窗
const debugStore = useDebugStore()
const environmentId = computed(() => debugStore.getEnvironmentId)
const { push } = useRouter()
const params = history.state
const treeRef = ref()
const loading = ref(false)
const tabData = ref()
const apiId = ref()
const queryInfo = ref()
import { useCache } from '@/hooks/web/useCache'
const { wsCache } = useCache()
const environmentParams = computed(() => wsCache.get('enviromentParams'))
/**
 * 接口或者用例点击获取数据
 * */
const handleTreeNodeClick = async (data) => {
  loading.value = true
  try {
    apiId.value = data.id
    appStore.setSelectProject(params.id)
    debugStore.setEnvironmentId(params.environmentId)
    tabData.value = await DebugApi.getApiInfo1({ id: data.id })
    // const interfacePostList = await DebugApi.getPostProcessorList({ id: data.id })
    tabData.value.name = tabData.value.apiVO.name
    tabData.value.apiRequestParamsVO = {
      requestContentType: tabData.value.apiVO.requestContentType,
      // post: interfacePostList,
      ...tabData.value.apiRequestParamsVO
    }
    tabData.value.info = {
      tag: '接口',
      name: tabData.value.apiVO.name,
      requestType: tabData.value.apiVO.requestType || '',
      url: tabData.value.apiVO.url || '',
      params: tabData.value.apiRequestParamsVO.params || [],
      body: tabData.value.apiRequestParamsVO.body || '',
      bodyForm: tabData.value.apiRequestParamsVO.bodyForm || [],
      headers: tabData.value.apiRequestParamsVO.headers || [],
      cookie: tabData.value.apiRequestParamsVO.cookie || [],
      auth: tabData.value.apiRequestParamsVO.auth || '',
      requestContentType: tabData.value.apiVO.requestContentType || '',
      // post: interfacePostList,
      projectParamas: { ...params }
    }
    tabData.value.apiVO.projectParamas = { ...params }
    tabData.value.response = {
      requestHeaderList: [],
      requestBody: '',
      requestParamsList: [],
      responseHeaders: [],
      responseContent: '',
      extractorResponse: [],
      assertInfos: [],
      imageUrl: '',
      responseResult: {
        responseCode: '',
        responseTime: '',
        responseSize: '',
        responseResult: '',
        requestUrl: '',
        cookies: [],
        responseContentType: ''
      }
    }
    queryInfo.value = tabData.value.info
  } catch (error) {
    console.log(error)
  } finally {
    loading.value = false
  }
}
const split = ref(1)

const toDebug = () => {
  split.value = 0.7
}

const toCopy = async () => {
  // 克隆的二次确认
  await ElMessageBox.confirm(`是否克隆项目${params.name}？`, '克隆项目', {
    confirmButtonText: '确 认',
    cancelButtonText: '取 消'
  })
    .then(async () => {
      loading.value = true
      const data = await apihubApi.cloneApi({
        projectId: params.id,
        environmentId: params.environmentId
      })
      message.success('克隆成功')
      loading.value = false
      const notify = ElNotification.success({
        title: '去查看',
        message: `已将${params.name}克隆到项目列表，点击查看`,
        onClick() {
          push({ path: '/apiManage/debug' })
          appStore.setSelectProject(data)
          debugStore.setEnvironmentId(null)
          notify.close()
        },
        duration: 0
      })
    })
    .catch((error) => {
      console.log(error)
      loading.value = false
    })
}

const toExport = async () => {
  // 导出的二次确认
  await ElMessageBox.confirm(`是否导出${params.name}项目接口？`, '导出接口', {
    confirmButtonText: '确 认',
    cancelButtonText: '取 消'
  })
    .then(async () => {
      loading.value = true
      const data = await apihubApi.exportApi({ projectId: params.id })
      message.success('导出成功')
      loading.value = false
      download.json(data, `${params.name}.json`)
    })
    .catch((error) => {
      console.log(error)
      loading.value = false
    })
}

const closeDebug = () => {
  split.value = 1
}

const handlePostData = (list) => {
  if (!list || !list.length) return []
  return list.map((item) => {
    return {
      stepId: item.stepId,
      type: item.type,
      status: item.status ? 0 : 1
    }
  })
}
const debugloading = ref(false)
/** 调试 */
const handleDebug = async () => {
  debugloading.value = true
  try {
    let paramsValue = []
    let url = ''
    if (queryInfo.value.url?.indexOf('http') == -1) {
      // 有环境服务
      url = `${params.conditionUrl}${queryInfo.value.url}`
    } else {
      url = queryInfo.value.url
    }
    if (
      ['form-data', 'x-www-form-urlencoded'].includes(queryInfo.value.requestContentType) &&
      queryInfo.value.bodyForm?.length
    ) {
      paramsValue = queryInfo.value.bodyForm || []
    } else {
      paramsValue = queryInfo.value.params || []
    }
    if (queryInfo.value.auth) {
      if (!queryInfo.value.headers?.length) {
        queryInfo.value.headers = [
          {
            keyName: 'Authorization',
            keyValue: queryInfo.value.auth,
            keyType: 'string'
          }
        ]
      } else {
        queryInfo.value.headers =
          (typeof queryInfo.value.headers == 'string'
            ? JSON.parse(queryInfo.value.headers)
            : queryInfo.value.headers) || []
        const isHasAuthorization = queryInfo.value.headers.some((q) => q.keyName == 'Authorization')
        if (isHasAuthorization) {
          queryInfo.value.headers = queryInfo.value.headers.map((item) => {
            if (item.keyName == 'Authorization') {
              return {
                ...item,
                keyValue: queryInfo.value.auth,
                keyType: 'string'
              }
            }
            return item
          })
        } else {
          queryInfo.value.headers = [
            ...(queryInfo.value.headers || []),
            {
              keyName: 'Authorization',
              keyValue: queryInfo.value.auth,
              keyType: 'string'
            }
          ]
        }
      }
    } else {
      // queryInfo.headers = JSON.parse(queryInfo.headers) || []
      queryInfo.value.headers =
        (typeof queryInfo.value.headers == 'string'
          ? JSON.parse(queryInfo.value.headers)
          : queryInfo.value.headers) || []
    }
    const varList = wsCache.get('enviromentParams').envVarList
    const apiParams = {
      // projectId: params.id,
      // environmentId: params.environmentId,
      protocal: 'https',
      requestType: queryInfo.value.requestType,
      url: url,
      requestContentType: queryInfo.value.requestContentType || '',
      requestHeaderList: queryInfo.value.headers,
      requestParamsList: paramsValue,
      requestBodyList: [],
      requestBody: queryInfo.value.body || '',
      postProcessors: handlePostData(queryInfo.value.post),
      envVarsList: (typeof varList == 'string' ? JSON.parse(varList) : varList) || []
    }
    let res = {} as any
    res = await DebugApi.apiDebug1(apiParams)
    let {
      responseHeaders,
      responseContent,
      requestBody,
      requestHeaderList,
      requestParamsList,
      responseResult,
      responseCode,
      responseTime,
      responseSize,
      requestUrl,
      cookies,
      responseContentType,
      extractorResponse,
      assertInfos,
      imageUrl
    } = res
    /** 响应内容存储到对应tab */
    tabData.value.response = {
      requestHeaderList,
      requestBody,
      requestParamsList,
      responseHeaders,
      responseContent,
      extractorResponse,
      assertInfos,
      imageUrl,
      responseResult: {
        responseCode,
        responseTime,
        responseSize,
        responseResult,
        requestUrl,
        cookies,
        responseContentType
      }
    }
  } catch (error) {
    console.log(error)
  } finally {
    debugloading.value = false
  }
}

/** 请求form、参数等变化后，放到对应tab中 */
const handleQueryValue = (value) => {
  if (!queryInfo.value) return
  queryInfo.value = {
    protocal: value.query.protocal,
    requestType: value.query.requestType,
    url: value.query.url,
    requestContentType: value.requestContentType,
    params: value.params,
    bodyForm: value.bodyForm,
    body: value.json,
    headers: value.headers,
    auth: value.auth,
    cookie: value.cookies,
    post: value.post
  }
}

/**
 * 环境变量操作
 * */
const environment = ref(environmentParams.value.environmentId)
const environments = ref([{
  id: environmentParams.value.environmentId,
  name: environmentParams.value.envName
}])
const environmentRef = ref()
const getEnvironments = async () => {
  // let res = await environmentApi.getEnvironmentList()
  // environments.value = res
  // debugStore.setEnvironments(res)
}
const openDialog = () => {
  environmentRef.value.open()
}
const changeEnv = async (val) => {
  debugStore.setEnvironmentId(val)
  const data = await environmentApi.getEnvironment({ systemEnvId: val })
  debugStore.setEnvironmentVars(data)
}
</script>
<style scoped lang="scss">
.apidoc {
  :deep(#tab-add) {
    position: relative;
    top: -5px;
    right: -1px;
    width: 40px;
    height: 40px;
    padding: 0;
    background: var(--el-bg-color);
  }

  :deep(.memorize_new_word) {
    text-decoration-color: transparent;
  }

  :deep(.demo-tabs) {
    height: 100%;

    >.el-tabs__header {
      .el-tabs__nav {
        border: none;

        .el-tabs__item {
          height: 30px;
          margin-top: 5px;
          margin-right: 5px;
          background: var(--el-bg-color-page);
          border: none;
          border-radius: 3px;
        }

        .el-tabs__item.is-active {
          background: #409eff22;
        }
      }
    }

    .el-tabs__new-tab {
      margin-right: 135px;
    }

    .el-tabs__content {
      height: calc(100% - 54px);

      .el-tab-pane {
        height: 100%;

        .query-com {
          height: 100%;

          .el-tabs {
            height: 100%;
          }
        }

        .response {
          position: relative;
          width: 100%;
          height: 100%;

          .result {
            position: absolute;
            top: 0;
            right: 10px;
            display: flex;
            width: 200px;
            height: 40px;
            font-size: 12px;
            justify-content: space-between;
            align-items: center;

            &-text {
              display: inline-block;
              padding: 2px 5px;
              border-radius: 4px;
            }
          }

          .el-tabs {
            height: 100%;
          }
        }
      }
    }
  }

  :deep(#tab-add:hover) {
    color: #333;
    cursor: pointer;
  }

  :deep(.el-card) {
    height: 100%;
  }

  :deep(.el-card__body) {
    height: calc(100% - 78px);
    padding: 10px !important;

    >div {
      height: 100%;
    }

    .custom-tree-node {
      display: flex;
      justify-content: space-between;
      width: calc(100% - 20px);
      height: 100%;
      line-height: 26px;

      >span:first-child {
        width: calc(100% - 25px);

        small {
          width: calc(100% - 25px);
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
      }

      .operation {
        display: none;
        margin-right: 15px;
      }

      &:hover {
        .operation {
          display: block;
        }
      }
    }
  }

  :deep(.el-tree) {
    height: calc(100% - 45px);
    overflow: hidden;

    >.el-tree-node {
      height: 100%;
      overflow: auto;
      // position: relative;
      // right: -10px;

      .el-tree-node__content {
        display: flex;
      }
    }
  }

  .method {
    margin-right: 10px;
  }


  /* 拖拽相关样式 */

  /* 包围div样式 */
  .content {
    display: flex;
    width: 100%;
    height: 100%;
    overflow: hidden;
    background: var(--el-bg-color);
  }

  /* 左侧div样式 */
  .content-left {
    position: relative;
    display: flex;
    width: 300px;
    height: 100%;
    max-height: calc(0px + 100vh);
    min-width: 250px;
    overflow: auto;
    flex-grow: 0;
    flex-shrink: 0;
    flex-direction: column;
    scrollbar-width: none;

    .header {
      display: flex;
      margin: 16px 24px;
      align-items: center;

      .avatat {
        display: block;
        width: 24px;
        height: 24px;
        object-fit: cover;
        border: 1px solid #fafafa;
        border-radius: 8px;
      }

      .title {
        margin-left: 8px;
        font-size: 16px;
        font-weight: 600;
        color: rgb(16 24 40 / 80%);
      }
    }
  }

  /* 拖拽区div样式 */
  .resize {
    position: relative;
    top: 45%;
    float: left;
    width: 10px;
    height: 50px;
    margin-top: -10px;

    /* z-index: 99999; */
    font-size: 32px;
    color: white;
    cursor: w-resize;
    background-color: #d6d6d6;
    background-position: center;
    background-size: cover;
    border-radius: 5px;
  }

  /* 拖拽区鼠标悬停样式 */
  .move:hover {
    color: #444;
  }

  /* 右侧div'样式 */
  .content-mid {
    position: relative;
    float: left;
    width: 75%;

    /* 右侧初始化宽度 */
    height: 100%;
    padding-bottom: 2%;
    padding-left: 10px;
    background: var(--el-bg-color);
    box-shadow: -1px 4px 5px 3px rgb(0 0 0 / 11%);
    box-sizing: border-box;
    flex: 1;

    :deep(.query-com) {
      height: 100%;

      .el-tabs {
        height: 100%;

        .el-tabs__content {
          height: calc(100% - 100px);

          >div {
            height: 100%;
          }
        }
      }
    }
  }

  .debug {
    height: 100%;
    padding: 10px 20px;

    .debug-header {
      display: flex;
      padding: 12px 16px;
      font-size: 18px;
      font-weight: 500;
      line-height: 18px;
      justify-content: flex-start;
      align-items: center;

      .close {
        width: 1em;
        height: 1em;
        margin-right: 8px;
        cursor: pointer;
      }

      .environment-select {
        margin-left: 5%;

        .el-select {
          .el-select__wrapper {
            border-radius: 4px 0 0 4px !important;
          }
        }
      }
    }

    :deep(.response) {
      height: 100%;

      .el-tabs {
        height: 100%;

        .el-tabs__content {
          height: calc(100% - 100px);

          >div {
            height: 100%;
          }
        }
      }
    }

    :deep(.query-com) {
      height: 100%;

      .el-tabs {
        height: 100%;

        .el-tabs__content {
          height: calc(100% - 100px);

          >div {
            height: 100%;
          }
        }
      }
    }
  }


}
</style>
